/*
  $Id: url_string.hh,v 1.5 2002/04/04 17:30:29 t16 Exp $

  URL string class.
  Copyright (C) 2002  Kasper Peeters <k.peeters@damtp.cam.ac.uk>

  This program and its components are free software; you can
  redistribute it and/or modify it under the terms of the GNU General
  Public License as published by the Free Software Foundation; either
  version 2, or (at your option) any later version.
 
  This program and its components are distributed in the hope that it
  will be useful, but WITHOUT ANY WARRANTY; without even the implied
  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
  the GNU General Public License for more details.
 
  You should have received a copy of the GNU General Public License in
  the file COPYING accompanying this program; if not, write to the
  Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

  Based on code Copyright (C) 1997 Andrew Lewycky <plewycky@oise.utoronto.ca>
  Reference: RFC 2068 
*/

#ifndef url_hh__
#define url_hh__

#include <string>
#include <map>

typedef std::map<std::string, std::string> strMap;
class url_string 
{
	public:
		url_string(const std::string& url, const std::string& referrer);
		url_string(const std::string& url, const url_string& referrer);
		url_string(const url_string& url);
		url_string(const std::string& url);
		url_string();
		virtual ~url_string();
		
		std::string       get_scheme(void) const;         // 'scheme:'
		std::string       get_original(void) const;       // string used in constructor, unparsed
		std::string       get_referrer(void) const;
		std::string       get_url(void) const;            // full url
		std::string       get_net_path(void) const;       // network host
		std::string       get_absolute_path(void) const;  // always return full path
		std::string       get_relative_path(void) const;  // in case the url was relative
		std::string       get_object(void) const;         // path removed, just the file
		std::string       get_parameters(void) const;     // ';parameters'
		int             	get_port(void) const;
		std::string       get_query(void) const;          // '?query'
		std::string       get_fragment(void) const;       // '#fragment'
		std::string       get_username() const;
		std::string       get_passwd() const;

		std::string		  get_param(const std::string& key) const;
		
		url_string& operator=(const url_string &);
		
		void              set_username(const std::string&);
		void              set_passwd(const std::string&);
	protected:
		virtual int default_port(void) const;

		/* Decode the URL as if it were a relative URL starting at iterator */
		/* All the following functions assuming they are working on original_url */
		virtual void DoRelDecode(std::string::const_iterator) const;
		virtual std::string::const_iterator DecodeScheme(std::string::const_iterator) const;
		virtual std::string::const_iterator DecodeNetPath(std::string::const_iterator) const;
		virtual std::string::const_iterator DecodeAbsPath(std::string::const_iterator) const;
		virtual std::string::const_iterator DecodeRelPath(std::string::const_iterator) const;
		virtual std::string::const_iterator DecodeParams(std::string::const_iterator) const;
		virtual std::string::const_iterator DecodeQuery(std::string::const_iterator) const;
		virtual std::string::const_iterator DecodeFragment(std::string::const_iterator) const;

		/* Called if the URL starts with scheme:, if you don't do anything
			(default), then DoRelDecode is called after scheme: */
		virtual std::string::const_iterator HandleAbs(std::string::const_iterator) const;
		void         finish_decoding_(void) const;
		virtual void fixup_(void) const;
		
		void		 SpliteParams(void);
	public:
		strMap paramsMap;
	private:
		
		std::string original_url;     /* What was given in constructor */
		std::string referrer;         /* What URL this was embedded in (copy of it) */

		mutable std::string url;           /* A non-relative URL created from above */
		mutable std::string scheme;       /* First section of URL */
		mutable std::string net_path;     /* Hostname, usually */
		mutable std::string query;
		mutable std::string fragment;
		mutable std::string passwd;
		mutable std::string username;
		mutable int         port;
		
		mutable std::string abs_path;     /* Absolute path */
		mutable std::string rel_path;     /* Relative path */
		mutable std::string params;
		
		mutable bool is_relative_;              /* If starts with scheme:, is not relative*/
		mutable bool decoding_finished_;        /* Whether we have finished parsing the URL */
};


#endif
